<template>
    <div class="captcha-wrapper" @click="refreshCaptcha">
        <canvas ref="canvas" :width="width" :height="height" class="captcha-canvas" />
        <div class="captcha-mask">
            <span class="refresh-text">点击刷新</span>
        </div>
    </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';

const props = defineProps({
    width: {
        type: Number,
        default: 120
    },
    height: {
        type: Number,
        default: 40
    },
    length: {
        type: Number,
        default: 4
    }
});

const canvas = ref(null);
const captchaText = ref('');

const generateCaptcha = () => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let text = '';
    for (let i = 0; i < props.length; i++) {
        text += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    captchaText.value = text;
    return text;
};

const getRandomColor = () => {
    const r = Math.floor(Math.random() * 256);
    const g = Math.floor(Math.random() * 256);
    const b = Math.floor(Math.random() * 256);
    return `rgb(${r},${g},${b})`;
};

const drawCaptcha = () => {
    const ctx = canvas.value.getContext('2d');
    ctx.clearRect(0, 0, props.width, props.height);
    ctx.font = '30px Arial';
    ctx.fillStyle = getRandomColor();

    const captcha = generateCaptcha();
    for (let i = 0; i < captcha.length; i++) {
        const x = (props.width / (props.length + 1)) * (i + 1);
        const y = props.height / 2 + Math.random() * 10 - 5;
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate((Math.random() - 0.5) * (Math.PI / 4));
        ctx.fillText(captcha[i], 0, 0);
        ctx.restore();
    }

    for (let i = 0; i < 5; i++) {
        ctx.beginPath();
        ctx.strokeStyle = getRandomColor();
        ctx.moveTo(Math.random() * props.width, Math.random() * props.height);
        ctx.lineTo(Math.random() * props.width, Math.random() * props.height);
        ctx.stroke();
    }
};

const refreshCaptcha = () => {
    drawCaptcha();
};

onMounted(() => {
    drawCaptcha();
});

const getCaptchaText = () => {
    return captchaText.value;
};

defineExpose({
    getCaptchaText
});
</script>

<style scoped lang="scss">
.captcha-wrapper {
    position: relative;
    cursor: pointer;
    border-radius: 6px;
    overflow: hidden;
    transition: transform 0.2s;

    &:hover {
        transform: scale(1.05);

        .captcha-mask {
            opacity: 1;
        }
    }
}

.captcha-mask {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.3s;
}

.refresh-text {
    color: white;
    font-size: 12px;
    font-weight: 500;
}
</style>